﻿using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Tasks;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using TheVerge.Base;
using TheVerge.Phone.Pages;
using TheVerge.Base.Platform;
using TheVerge.Phone.Imp;

namespace TheVerge.Phone.Controls
{
    public class AppBarState
    {
        public IApplicationBarIconButton[] Butons { get; set; }
        public IApplicationBarMenuItem[] Items { get; set; }
        public bool IsMini { get; set; }
    }

    public static class AppBarHelper
    {

        #region Private Vartiables
        private static IApplicationBar Bar { get { return GetBar(); } }
        private static ArticleEntry ActiveArticle { get { return App.MainVM.ActiveArticle; } }

        private static IPinner Pinner = new PhonePinner();

        private static IApplicationBar GetBar()
        {
            var currentPage = ((App)Application.Current).RootFrame.Content as PhoneApplicationPage;
            if (currentPage != null && currentPage.ApplicationBar != null)
                return currentPage.ApplicationBar;

            return EmptyBar.Default;
        }

        private class EmptyBar : IApplicationBar
        {
            public static readonly EmptyBar Default = new EmptyBar();

            public Color BackgroundColor { get; set; }

            private static List<object> buttons = new List<object>();
            public System.Collections.IList Buttons
            {
                get { return buttons; }
            }

            public double DefaultSize { get { return 0D; } }

            public Color ForegroundColor { get; set; }

            public bool IsMenuEnabled { get; set; }

            public bool IsVisible { get; set; }

            private static List<object> menuItems = new List<object>();
            public System.Collections.IList MenuItems
            {
                get { return menuItems; }
            }

            public double MiniSize { get { return 0D; } }

            public ApplicationBarMode Mode { get; set; }

            public double Opacity { get; set; }

            public event EventHandler<ApplicationBarStateChangedEventArgs> StateChanged = delegate { };
        }

        #region Menu Buttons
        private static ApplicationBarMenuItem AboutItem = new ApplicationBarMenuItem("About");
        public static ApplicationBarMenuItem PinToStartItem = new ApplicationBarMenuItem("Pin to Start");
        public static ApplicationBarMenuItem SettingsItem = new ApplicationBarMenuItem("Settings");
        public static ApplicationBarMenuItem SaveImageItem = new ApplicationBarMenuItem("Save to phone");

        public static ApplicationBarIconButton ConfirmButton =
            new ApplicationBarIconButton(new Uri(@"/Images/appbar.check.rest.png", UriKind.Relative)) { Text = "Confirm" };
        public static ApplicationBarIconButton CancelButton =
            new ApplicationBarIconButton(new Uri(@"/Images/appbar.cancel.rest.png", UriKind.Relative)) { Text = "Cancel" };

        public static ApplicationBarIconButton NewsButton =
            new ApplicationBarIconButton(new Uri(@"/Images/appbar.news.png", UriKind.Relative)) { Text = "News" };
        public static ApplicationBarIconButton SectionsButton =
            new ApplicationBarIconButton(new Uri(@"/Images/appbar.sections.png", UriKind.Relative)) { Text = "Sections" };
        public static ApplicationBarIconButton ForumButton =
            new ApplicationBarIconButton(new Uri(@"/Images/appbar.comments.png", UriKind.Relative)) { Text = "Forums" };
        public static ApplicationBarIconButton FollowingButton =
            new ApplicationBarIconButton(new Uri(@"/Images/appbar.following.png", UriKind.Relative)) { Text = "Following" };
        public static ApplicationBarIconButton MediaButton =
            new ApplicationBarIconButton(new Uri(@"/Images/appbar.media.png", UriKind.Relative)) { Text = "Media" };

        public static ApplicationBarIconButton IEButton =
            new ApplicationBarIconButton(new Uri(@"/Images/appbar.ie.png", UriKind.Relative)) { Text = "Open in IE" };
        public static ApplicationBarIconButton ShareButton =
            new ApplicationBarIconButton(new Uri(@"/Images/appbar.share.png", UriKind.Relative)) { Text = "Share" };
        
        public static ApplicationBarIconButton CommentsButton =
            new ApplicationBarIconButton(new Uri(@"/Images/appbar.comments.png", UriKind.Relative)) { Text = "Comments" };

        #endregion
        #endregion

        static AppBarHelper()
        {
            ShareButton.Click += (s, e) =>
            {
                if (ShareAction != null)
                    ShareAction();
                return;
                
            };
            IEButton.Click += (s, e) =>
            {
                var wbt = new WebBrowserTask();
                wbt.Uri = new Uri(ActiveArticle.Url, UriKind.Absolute);
                wbt.Show();
            };

            AboutItem.Click += (s, e) => LaunchIfDifferentPage(@"/Pages/AboutPage.xaml");
            ForumButton.Click += (s, e) => LaunchIfDifferentPage(@"/Pages/ForumsPage.xaml");
            NewsButton.Click += (s, e) => LaunchIfDifferentPage(@"/Pages/NewsPage.xaml");
            MediaButton.Click += (s, e) => LaunchIfDifferentPage(@"/Pages/MediaPage.xaml");
            SectionsButton.Click += (s, e) => LaunchIfDifferentPage(@"/Pages/SectionsPage.xaml");


            CancelButton.Click += (s, e) => SafeInvoke(CancelAction);
            CommentsButton.Click += (s, e) => SafeInvoke(CommentsAction);
            ConfirmButton.Click += (s, e) => SafeInvoke(ConfirmAction);
            SaveImageItem.Click += (s, e) => SafeInvoke(SaveImageAction);

            PinToStartItem.Click += (s, e) =>
            {
                var pinnable = App.MainVM.ActivePinnable;
                Pinner.Pin(pinnable);
            };
            SettingsItem.Click += (s, e) => LaunchIfDifferentPage(@"/Pages/SettingsPage.xaml");
        }

        #region Public
        public static Action ConfirmAction { get; set; }
        public static Action CommentsAction { get; set; }
        public static Action CancelAction { get; set; }
        public static Action SaveImageAction { get; set; }
        public static Action ShareAction { get; set; }

        public static AppBarState CurrentAppBar
        {
            get
            {
                return new AppBarState
                {
                    Butons = Bar.Buttons.Cast<IApplicationBarIconButton>().ToArray(),
                    Items = Bar.MenuItems.Cast<IApplicationBarMenuItem>().ToArray(),
                    IsMini = Bar.Mode == ApplicationBarMode.Minimized ? true : false,
                };
            }
        }

        public static bool IsVisible { get { return Bar.IsVisible; } set { Bar.IsVisible = value; } }

        public static void LaunchIfDifferentPage(string pageUri)
        {
            var currentUri = ((App)Application.Current).RootFrame.CurrentSource.ToString();

            if (currentUri == pageUri) return;

            (Application.Current.RootVisual as PhoneApplicationFrame).Navigate(new Uri(pageUri, UriKind.Relative));
        }

        public static void Load(AppBarState state)
        {
            Load(state.Butons, state.Items, state.IsMini);
        }
        public static void Load(IEnumerable<IApplicationBarIconButton> buttons, IEnumerable<IApplicationBarMenuItem> menuItems, bool mini)
        {
            Clear();
            bool barHasButtonsOrItems = false;

            if (buttons != null)
                foreach (var button in buttons)
                {
                    Bar.Buttons.Add(button);
                    barHasButtonsOrItems = true;
                }

            if (menuItems != null)
                foreach (var item in menuItems)
                {
                    Bar.MenuItems.Add(item);
                    barHasButtonsOrItems = true;
                }

            if (!Bar.MenuItems.Contains(AboutItem))
                Bar.MenuItems.Add(AboutItem);

            Bar.Mode = mini ? ApplicationBarMode.Minimized : ApplicationBarMode.Default;

            Bar.IsVisible = barHasButtonsOrItems; //-- No need to show this if there's nothing in it
        }

        public static void LoadFromPage()
        {
            var currentPage = ((App)Application.Current).RootFrame.Content as BasePage;
            if (currentPage != null)
                currentPage.LoadBar();
        }
        #endregion

        #region Helper Methods
        private static void Clear()
        {
            Bar.Buttons.Clear();
            Bar.MenuItems.Clear();
        }

        private static void SafeInvoke(Action a)
        {
            if (a != null) a();
        }
        #endregion
    }
}
